Navigation
是Jetpack中的頁面轉換元件。
用來取代FragmentTransaction
,
以GUI方式呈現頁面流程,
能更方便的管理各Fragment
之間的跳轉關係。
如圖:
假設A Fragment
跳轉到B Fragment
Gradle
新增dependencies
navigation.xml
Activity
的xml
中,新增一個<FragmentContainerView/>
元件,navigation.xml
。A Fragment
找到內部已透過2綁定對應的NavController
,執行頁面跳轉。接著就來實做看看吧
Gradle
新增dependencies
project層的build.gradle
dependencies {
val nav_version = "2.3.5"
classpath
"androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
// Java language implementation
implementation("androidx.navigation:navigation-fragment:$nav_version")
implementation("androidx.navigation:navigation-ui:$nav_version")
// Kotlin
implementation("androidx.navigation:navigation-fragment-ktx:$nav_version")
implementation("androidx.navigation:navigation-ui-ktx:$nav_version")
// Feature module Support
implementation("androidx.navigation:navigation-dynamic-features-fragment:$nav_version")
// Testing Navigation
androidTestImplementation("androidx.navigation:navigation-testing:$nav_version")
// Jetpack Compose Integration
implementation("androidx.navigation:navigation-compose:2.4.0-alpha08")
}
module層的build.gradle
apply plugin: "androidx.navigation.safeargs.kotlin"
navigation.xml
在res
按下右鍵,新增Android resource file
。
Resource Type
選擇Navigation
。
在xml
中新增對應的fragment
:
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
app:startDestination="@id/aFragment"
android:id="@+id/nav_graph">
<fragment
android:id="@+id/aFragment"
android:name="com.example.cashdog.cashdog.AFragment"
android:label="@string/label_blank"
tools:layout="@layout/fragment_blank" >
<action
android:id="@+id/action_aFragment_to_bFragment"
app:destination="@id/bFragment" />
</fragment>
<fragment
android:id="@+id/bFragment"
android:name="com.example.cashdog.cashdog.BFragment"
android:label="@string/label_blank_2"
tools:layout="@layout/fragment_blank_fragment2" />
</navigation>
<action>
的作用為A Fragment
跳轉至B Fragment
。
A Fragment
和B Fragment
的Activity
底下,新增一個<FragmentContainerView/>
元件,並綁定navigation.xml
。<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
</FrameLayout>
android:name="androidx.navigation.fragment.NavHostFragment"
用來宣告實現此 Fragment
為 NavHostFragment
app:defaultNavHost="true"
true
會攔截返回按鍵,讓頁面返回上一層,
不會退出Activity
。
上一層可以是Fragment
或Activity
。
app:navGraph="@navigation/nav_graph"
作用是將activity_main.xml
中的Fragment
與navigation
連接起來。
A Fragment
找到內部已透過2綁定對應的NavController
,執行頁面跳轉。NavController
的方法如下:
- Activity.findNavController(viewId: Int)
- Fragment.findNavController()
- View.findNavController()
寫法:
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
navController
為fragment
的navigation
。
假設透過按下AFragment
中的某個按鈕跳轉到BFragment
:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
view.findViewById<Button>(R.id.next)
.setOnClickListener {
val action = AFragmentDirections.actionAFragmentToBFragment()
view.findNavController().navigate(action)
}
}
就會切換到下一頁了。
參考: